
#include <iostream>
#include <string>
using namespace std;

#include <stdio.h>

#include "LogCommon.hpp"
#include "LogMessage.hpp"
#include "Logger.hpp"
#include "AppendFile.hpp"
#include "LogFile.hpp"
#include "AsynLogging.hpp"

tulun::AsynLogging *appfile = nullptr;

void WriteFile(const std::string &msg)
{
    appfile->append(msg);
}
void FlushFile()
{
    appfile->flush();
}
void funa()
{

    for (int i = 0; i < 10; ++i)
    {
        LOG_INFO << "funa i: " << i;
    }
}
void funb()
{
    for (int i = 10; i < 20; ++i)
    {
        LOG_INFO << "funb i: " << i;
    }
}

int main()
{
    appfile = new tulun::AsynLogging("qwer", 1024 * 512, 3);
    appfile->start();
    tulun::Logger::setOutput(WriteFile);
    tulun::Logger::setFlush(FlushFile);
    tulun::Logger::setLogLevel(tulun::LOG_LEVEL::TRACE);

    std::thread tha(funa);
    std::thread thb(funb);
    tha.join();
    thb.join(); 
    appfile->flush();
    appfile->stop();
    delete appfile;
    appfile = nullptr;
    return 0;
}

#if 0
// tulun::AppendFile *appfile = nullptr;
tulun::LogFile *appfile = nullptr;
void WriteFile(const std::string &msg)
{
    appfile->append(msg);
}
void FlushFile()
{
    appfile->flush();
}

int main()
{
    appfile = new tulun::LogFile("qwert");
    tulun::Logger::setOutput(WriteFile);
    tulun::Logger::setFlush(FlushFile);
    tulun::Logger::setLogLevel(tulun::LOG_LEVEL::TRACE);
    for (int i = 0; i < 100000; ++i)
    {
        LOG_TRACE << "qwert: " << i;
    }
    delete appfile;
    appfile = nullptr;
    return 0;
}

int main()
{
    tulun::Logger::setLogLevel(tulun::LOG_LEVEL::TRACE);
    cout << tulun::IndToStr[static_cast<int>(tulun::Logger::getLogLevel())] << endl;
    LOG_TRACE << "0";
    LOG_DEBUG << "1";
    LOG_INFO << "2";
    LOG_WARN << "3";
    LOG_ERROR << "4";
    LOG_FATAL << "5";
}

class AppendFile
{
private:
    FILE *fp;

public:
    AppendFile(const std::string filename)
    {
        fp = fopen(filename.c_str(), "wb");
        if (nullptr == fp)
            exit(1);
    }
    ~AppendFile()
    {
        fclose(fp);
        fp = nullptr;
    }

    void AddMesFile(const string &msg)
    {
        size_t n = fwrite(msg.c_str(), sizeof(char), msg.size(), fp);
    }
    void FileFlush()
    {
        fflush(fp);
    }
};

AppendFile outfile("qwerlog.log");
int AddInt(int a, int b)
{
    LOG_INFO << "Add Int a : " << a << " b : " << b;
    int c = a + b;
    return c;
}
int DivInt(int a, int b)
{
    LOG_INFO << "Div Int a : " << a << " b : " << b;
    if (0 == b)
    {
        LOG_FATAL << "Div 0: " << "b " << b;
    }
    int c = a / b;
    return c;
}
int main()
{
    tulun::Logger::setLogLevel(tulun::LOG_LEVEL::TRACE);
    tulun::Logger::setOutput(
        std::bind(&AppendFile::AddMesFile, &outfile, std::placeholders::_1));
    tulun::Logger::setFlush(std::bind(&AppendFile::FileFlush, &outfile));
    LOG_TRACE << "int main";
    int a = 10, b = 2, x = 1;
    int c = 0;
    LOG_TRACE << "call AddInt";
    c = AddInt(a, b);
    LOG_TRACE << "call DivInt";
    c = DivInt(a, b);
    LOG_TRACE << "call DivInt";
    c = DivInt(a, x);
    LOG_TRACE << "end main";
    return 0;
}

int main()
{
    // tulun::Logger::setLogLevel(tulun::LOG_LEVEL::TRACE);
    int a = 10, b = 20;
    LOG_TRACE << "QWERT " << a;
    LOG_TRACE << "QWERT " << b;
    LOG_INFO << "QWERT";
    LOG_INFO << "QWERT";
    LOG_ERROR << "QWERT";
    LOG_FATAL << "QWERT";
    return 0;
}

int func(int a, int b)
{
    LOG_TRACE << "AddInt: " << "a " << a << "b " << b;
    int c = a + b;
    return c;
}
int main()
{
    LOG_TRACE << "call main ";
    int x = 10, y = 20;
    int c = func(x, y);
    cout << c << endl;
    LOG_TRACE << "main end";
    return 0;
}

int main()
{
    tulun::Logger log(tulun::LOG_LEVEL::DEBUG,
                          __FILE__, __func__, __LINE__);
    log.stream() << "QWER";
    return 0;
}


struct Student
{
    std::string s_id;
    std::string s_name;
    std::string s_sex;
    int s_age;
};
int main()
{
    tulun::LogMessage logmes(tulun::LOG_LEVEL::DEBUG,
                             __FILE__, __func__, __LINE__);
    Student s1{"2024001", "qwert", "man", 12};
    logmes << s1;
    return 0;
}


int func()
{
    tulun::LogMessage logmes(tulun::LOG_LEVEL::DEBUG,
                             __FILE__, __func__, __LINE__);
    std::string lm = logmes.toString();
    cout << lm << endl;

    logmes << "qwert";
    lm = logmes.toString();
    cout << lm << endl;

    logmes << 12;
    cout << logmes.toString() << endl;
    logmes << 12.25;
    cout << logmes.toString() << endl;
    return 0;
}
int main()
{
    func();
    return 0;
}


int func()
{
    tulun::LogMessage logmes(tulun::LOG_LEVEL::DEBUG,
                             __FILE__, __func__, __LINE__);
    std::string lm = logmes.toString();
    cout << lm << endl;
    return 0;
}
int main()
{
    func();
    cout << __FILE__ << endl;
    cout << __func__ << endl;
    cout << __DATE__ << endl;
    cout << __TIME__ << endl;
    cout << __LINE__ << endl;
    cout << __STDC__ << endl;
    cout << __cplusplus << endl;
}

int main()
{
    tulun::LOG_LEVEL le = tulun::LOG_LEVEL::INFO;
    cout << tulun::GetIndexToStr(le) << endl;
    cout << tulun::IndexToStr[static_cast<int>(le)] << endl;
    cout << tulun::IndToStr[static_cast<int>(le)] << endl;
    cout << tulun::ImapStr.at(le) << endl;
    return 0;
}

int main()
{
    tulun::LOG_LEVEL le = tulun::LOG_LEVEL::INFO;
    cout << static_cast<int>(le) << endl;
    le=tulun::LOG_LEVEL::FATAL;

    return 0;
}

#include "Timestamp.hpp"

int main()
{
    int n = 10000;
    double dx = 12.25;
    tulun::Timestamp start = tulun::Timestamp::Now();

    for (int i = 0; i < n; ++i)
    {
        dx = dx + 0.001;
    }
    tulun::Timestamp done = tulun::Timestamp::Now();
    time_t diff = tulun::diffMicro(done, start);
    cout << "diff: " << diff << endl;
}


int main()
{
    tulun::Timestamp ts;
    ts.now();

    std::string strbuff = ts.toString();
    cout << strbuff << endl;
    std::string strm = ts.toFormattedString(false);
    cout << strm << endl;
    std::string strmic = ts.toFormattedString(true);
    cout << strmic << endl;
    return 0;
}

#endif